﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using ArchivesAdmin.Util;
using ArchivesAdmin.Util.Extension;
using ArchivesAdmin.Util.Model;
using ArchivesAdmin.Entity.StorageManage;
using ArchivesAdmin.Model.Param.StorageManage;
using ArchivesAdmin.Service.StorageManage;
using ArchivesAdmin.Model.Result.StorageManage;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;
using ArchivesAdmin.Service;

namespace ArchivesAdmin.Business.StorageManage
{
    /// <summary>
    /// 创 建：admin
    /// 日 期：2021-06-19 09:36
    /// 描 述：业务类
    /// </summary>
    public class BarLibBLL
    {
        private BarLibService barLibService = new BarLibService();

        StringBuilder allArchivesId = new StringBuilder();

        #region 获取数据
        public async Task<TData<List<BarLibEntity>>> GetList(BarLibListParam param)
        {
            TData<List<BarLibEntity>> obj = new TData<List<BarLibEntity>>();
            obj.Result = await barLibService.GetList(param);
            obj.TotalCount = obj.Result.Count;
            obj.Tag = 1;
            return obj;
        }

        public async Task<TData<List<BarLibEntity>>> GetPageList(BarLibListParam param, Pagination pagination)
        {
            TData<List<BarLibEntity>> obj = new TData<List<BarLibEntity>>();
            obj.Result = await barLibService.GetPageList(param, pagination);
            obj.TotalCount = pagination.TotalCount;
            obj.Tag = 1;
            return obj;
        }

        public async Task<TData<BarLibEntity>> GetEntity(long id)
        {
            TData<BarLibEntity> obj = new TData<BarLibEntity>();
            obj.Result = await barLibService.GetEntity(id);
            if (obj.Result != null)
            {
                obj.Tag = 1;
            }
            return obj;
        }
        #endregion


        #region 提交数据
  
        /// <summary>
        /// 打印盒码： 从 param中解析页面中传来的参数，
        /// 生成1-n个entity，存入后台数据库中
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>

        public async Task<TData<string>> PrintBoxCode(BarLibPrintParam param, string frompage)
        {
            TData<string> obj = new TData<string>();
            int rows = 0;
            BarLibEntity entity = null; 
            int start_child = 0;
            int end_child = 0;
            int arcNums = 0;
            try
            {
                arcNums = int.Parse(param.ArchiveIdEnd) - int.Parse(param.ArchiveIdStart) + 1;
            }
            catch { 
            }

            int p = 0;     //记录开始id的状态值


            //if 分支 created by XQ 2021-7-7   
            if (!string.IsNullOrEmpty(param.ArrayIds)) {
                string[] str = param.ArrayIds.Split(",");   //单个：Z49·2020·00001·01 

                int i = 0,j=0;
                string childId="";
                string q = str[0].Split("·")[2];
                int count = 0;
                NextCodeSortInfo info = GetNextBoxCode(param.ArchiveType, param.ArchiveYear, frompage);   // Z31 ， 2018

                for (j = 0; j < arcNums; j++)
                {
                    for (i = count; i < str.Length; i++)
                    {
                        if (str[i].Split("·")[2] == q)
                        {
                            childId += str[i].Split("·")[3] + ";";
                            count++;
                        }
                    }
                    if(count<str.Length)
                        q=str[count].Split("·")[2];                   
                    entity = new BarLibEntity();
                    entity.Archiveid = str[count-1].Substring(0, str[count-1].Length - 3);
                    entity.Archivechildid = childId;
                    entity.Arctype = param.ArchiveType;
                    entity.Arcyear = param.ArchiveYear;
                    entity.Category = "BOX";                 
                    entity.Boxcode = info.NextBoxCode;
                    entity.Sortnum = info.NextSortNum;
                    entity.Bincode = "";
                    entity.Binsecret = "";
                    entity.Isprinted = 0;
                    if (frompage == "BarLib")
                        entity.Tempbincode = "-";   // 来自  档案封箱  页面
                    else
                        entity.Bincode = "-";   // 来自  档案周转  页面
                    entity.Isfinished = 0;
                    entity.Shelf = "";
                    entity.Remark = "";
                    entity.Printway = param.PrintWay;
                    entity.Isscreenchildid = 1;
                    rows++;
                    Task t = barLibService.PrintOneBoxCode(entity, j==arcNums-1, p);
                    p++;
                    childId = "";
                }
            }
            else { 
                if (string.IsNullOrEmpty(param.ArchiveIdEnd))
                { //没有输入结束码，意味着只有一个档案号,数据库只有1条记录
                    entity = new BarLibEntity();
                    entity.Archiveid = GetFullArchiveId(param, 0);
                    allArchivesId = new StringBuilder();
                    //有起始子号
                    if (!string.IsNullOrEmpty(param.ArchiveIdStartChild))
                    {

                        try
                        {
                            start_child = int.Parse(param.ArchiveIdStartChild);
                            end_child = int.Parse(param.ArchiveIdEndChild);
                        }
                        catch
                        { 
                        }
                        //有截止子号
                        if (!string.IsNullOrEmpty(param.ArchiveIdEndChild))
                        {
                            for (int i = start_child; i <= end_child; i++)
                            {
                                entity.Archivechildid = entity.Archivechildid + i.ToString().PadLeft(2, '0') + ';';
                                //list.Add(entity.Archiveid + " ( " + i.ToString().PadLeft(2, '0') + ")");
                            }
                        }
                        //无截止子号,即有0或1个子号
                        else
                        {
                            entity.Archivechildid = entity.Archivechildid + param.ArchiveIdStartChild.PadLeft(2, '0');
                        }

                    }


                    entity.Archiveid = GetFullArchiveId(param, 0);
                    entity.Arctype = param.ArchiveType;
                    entity.Arcyear = param.ArchiveYear;
                    entity.Category = "BOX";
                    NextCodeSortInfo info = GetNextBoxCode(param.ArchiveType, param.ArchiveYear, frompage);   // Z31 ， 2018
                    entity.Boxcode = info.NextBoxCode;
                    entity.Sortnum = info.NextSortNum;
                    entity.Bincode = "";
                    entity.Binsecret = "";
                    entity.Isprinted = 0;
                    if (frompage == "BarLib")
                        entity.Tempbincode = "-";   // 来自  档案封箱  页面
                    else
                        entity.Bincode = "-";   // 来自  档案周转  页面
                    entity.Isfinished = 0;
                    entity.Shelf = "";
                    entity.Remark = "";
                    entity.Printway = param.PrintWay;
                    allArchivesId.Append(entity.Archiveid);
                    rows++;
                    Task t = barLibService.PrintOneBoxCode(entity, true,p);
                    p++;
                }

                //有截止档案号
                else
                {
                    // 一组档案号 -- 放到1个盒子里面
                    int start = int.Parse(param.ArchiveIdStart);
                    int end = int.Parse(param.ArchiveIdEnd);
                    allArchivesId = new StringBuilder();
                    try
                    {
                        start_child = int.Parse(param.ArchiveIdStartChild);
                        end_child = int.Parse(param.ArchiveIdEndChild);
                    }

                    catch
                    {

                    }

                    NextCodeSortInfo info = GetNextBoxCode(param.ArchiveType, param.ArchiveYear, frompage);  // 每次打印一个盒码

                    // 以下循环中，多个档案放到一个盒子中 --- 只要打印一个盒码
                    for (int i = start; i <= end; i++)
                    {
                        entity = new BarLibEntity();
                   
                        //有截止子号
                        if (!string.IsNullOrEmpty(param.ArchiveIdEndChild))
                        {

                            for (int j = start_child; j <= end_child; j++)
                            {
                                entity.Archivechildid = entity.Archivechildid + j.ToString().PadLeft(2, '0') + ';';
                            }
                        }
                        //无截止子号,即有0或1个起始子号
                        else
                        {
                            if(param.ArchiveIdStartChild!="")
                                entity.Archivechildid += param.ArchiveIdStartChild.PadLeft(2, '0');
                        }
                        entity.Archiveid = GetFullArchiveId(param, i - start);
                        entity.Arctype = param.ArchiveType;
                        entity.Arcyear = param.ArchiveYear;
                        entity.Category = "BOX";
                        entity.Boxcode = info.NextBoxCode;
                        entity.Sortnum = info.NextSortNum;
                        entity.Bincode = "";
                        entity.Binsecret = "";
                        entity.Isprinted = 0;
                        if (frompage == "BarLib")
                            entity.Tempbincode = "-";   // 来自  档案封箱  页面
                        else
                            entity.Bincode = "-";   // 来自  档案周转  页面 

                        entity.Isfinished = 0;
                        entity.Shelf = "";
                        entity.Remark = "";
                        entity.Printway = param.PrintWay;
                        allArchivesId.Append(entity.Archiveid);
                        rows++;
                        Task t = barLibService.PrintOneBoxCode(entity, i == end,p);   //一个盒子中放多个档案，就只针对第一个档案打印盒码，后面的档案号不再打印 盒号
                        p++;
                    }
                }
        }
                    
        // 再获取当前用户没有被分配箱码的所有盒码列表 
        var list2 = barLibService.GetBoxCodesNotMapped(param.ArchiveType, param.ArchiveYear, frompage);
            ArrayList arr = new ArrayList();
            foreach (var item in list2.Result.ToList())
            {
                if (!arr.Contains(item.Boxcode)) arr.Add(item.Boxcode);
            }

            obj.ResultList = arr;   //  --- 将返回到前端页面列表

            obj.Result = "共生成" + rows + "条盒码。";
            obj.Tag = 1;
            return obj;
        }

        // created by XQ  批量打印
        public async Task<TData<string>> BatchPrintBoxCode(string boxCodes)
        {
            string[] str = boxCodes.Split('Z');
            string startId = "";
            BarLibEntity entity = new BarLibEntity();
            foreach (string x in str)
            {
                if (x != "")
                {
                    entity = new BarLibEntity();
                    string childId = "";
                    string[] data = await barLibService.GetArchiveDataByCode(x.Insert(0, "Z"));
                    string allArchivesId = data[0];
                    string[] str1 = allArchivesId.Split(";");
                    startId = str1[0];
                    foreach (string p in str1)
                    {
                        if (!string.IsNullOrEmpty(p))
                            childId += await barLibService.GetArchiveChildIdByArchiveId(p) + "/";
                    }
                    entity.Boxcode = x.Insert(0, "Z");
                    entity.Archiveid = str1[str1.Length - 2];
                    entity.Isscreenchildid = int.Parse(data[1]);
                    PrinterHelper.PrintLabel(entity, startId, childId);
                }
            }
            TData<string> obj = new TData<string>();
            obj.Tag = 1;
            return obj;
        }


        public async Task<TData<string>> ReprintCode(string  code )
        {
            TData<string> obj = new TData<string>();
            barLibService.ReprintCode(code);
            obj.Tag = 1;
            return  obj;
        }

        // 获取需要重新打印的 箱码、 盒码 列表 （来源： 档案封箱、 档案周转）
        public async Task<List<BarLibEntity>> GetReprintCodes(string frompage)
        {             
            // 获取当前用户需要重打的  箱码、 盒码 列表 
            return await barLibService.GetReprintCodes( frompage);
            
        }


        public async Task<TData<string>> GetBoxCodesListNotFinished(BarLibPrintParam param, string frompage)
        {
            TData<string> obj = new TData<string>();
            // 再获取当前用户没有被分配箱码的所有盒码列表 
            var list2 = barLibService.GetBoxCodesNotMapped(param.ArchiveType, param.ArchiveYear, frompage);
            ArrayList arr = new ArrayList();
            foreach (var item in list2.Result.ToList())
            {
                if (!arr.Contains(item.Boxcode)) arr.Add(item.Boxcode);
            }

            obj.ResultList = arr;   //  --- 将返回到前端页面列表
            return obj;
        }
           

        /// <summary>
        /// 打印箱码: 针对先前的盒码，写入它们对应的箱码，并产生一条箱码记录
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<TData<string>> PrintBinCode(BarLibPrintParam param)
        {
            // param.Description = "<button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00001</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00002</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00003</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00004</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00005</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00006</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00007</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00008</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00009</button>
            // <button type=\"button\" class=\"btn btn-xs btn-info\">Z21-2019-H-00010</button>"
            // 用正则表达式，将 中的 param.Description 盒码取出来
            MatchCollection allMatchResults = null; 

            //开始字符串 
            string s1 = " btn-info\">";
            //结束字符串 
            string s2 = "</button>";
            Regex rg = new Regex("(?<=(" + s1 + "))[.\\s\\S]*?(?=(" + s2 + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            //string str = rg.Match(s).Value;
            allMatchResults = rg.Matches(param.Description);
            string boxcodes = "";
            foreach(Match m in allMatchResults)
            {
                boxcodes += m.Value + ";";
            }

            TData<string> obj = new TData<string>();

            BarLibEntity entity = new BarLibEntity();

            NextCodeSortInfo info = GetNextBinCode(param.ArchiveType, param.ArchiveYear  );  // Z31 ， 2018

            entity.Boxcode = boxcodes;
            entity.Bincode = info.NextBinCode;
            entity.Arctype = param.ArchiveType;
            entity.Arcyear =  param.ArchiveYear;
            entity.Category = "BIN";
            entity.Tempbincode = "-";
            await barLibService.PrintBinCode(entity);

            // 将新的箱码，返回到前端页面显示出来
            obj.Result = entity.Bincode;
            obj.Description = entity.Id.ToString();

            obj.Tag = 1;
             
            return obj;
        }

        /// <summary>
        /// 设置箱码对应的 密码锁 
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<TData<string>> SetBinSecret(BarLibPrintParam param)
        {
            TData<string> obj = new TData<string>();
            BarLibEntity entity = new BarLibEntity();
 
            entity.Id = long.Parse(param.EntityId) ;
            entity.Arctype = param.ArchiveType;
            entity.Arcyear = param.ArchiveYear;

            entity.Bincode = param.CurBinCode;    
            entity.Binsecret = param.BinSecure;

            await barLibService.SetBinSecret(entity);
            obj.Result = entity.Id.ParseToString();
            obj.Tag = 1;
            return obj;
        }

        #endregion


        #region 私有方法
        // 从 barlib 表中，找出某类别、某年档案的下一个盒子的code（1箱10盒）
        private NextCodeSortInfo GetNextBoxCode(string arccate, int arcyear, string frompage)
        {
            var list = barLibService.GetLatestBoxBinCodes(arccate, arcyear, "BOX" , frompage );  // 获得的盒码， 要注意  档案封箱的 SortNum 与 档案周转 的 SortNum 不要共用 ， 需要各自独立使用

            List<BarLibEntity> lst = list.Result.ToList();
            NextCodeSortInfo info = new NextCodeSortInfo();

            if (lst.Count == 1)
            {
                BarLibEntity entity = lst[0];

                int pos = entity.Boxcode.LastIndexOf('-');
                string prefix = entity.Boxcode.Substring(0, pos+1 );
                string postfix = entity.Boxcode.Substring(pos+1);
                int num = int.Parse(postfix) + 1;
                info.NextBoxCode = prefix + num.ToString().PadLeft(5, '0')  ;  // 盒码+1

                if (frompage == "BarLib"  &&  entity.Bincode != "-" )  // 找到的最新 盒码 记录， 是 档案封箱的
                {
                    if (entity.Sortnum == 10)
                    {                        
                        NextCodeSortInfo info2 = GetNextBinCode(arccate, arcyear);

                        info.NextBinCode = info2.NextBinCode;
                        info.NextSortNum = 1;
                    }
                    else
                    {                        
                        info.NextBinCode = entity.Bincode;
                        info.NextSortNum = entity.Sortnum + 1;
                    }
                }
                else if (frompage == "Circulation" && entity.Tempbincode != "-")  // 找到的最新 盒码 记录， 是 档案周转箱的
                {
                    if (entity.Sortnum == 10)
                    {
                        NextCodeSortInfo info2 = GetNextBinCode(arccate, arcyear);
                         
                        info.NextSortNum = 1;
                    }
                    else
                    { 
                        info.NextSortNum = entity.Sortnum + 1;
                    }
                }
                else
                    info.NextSortNum = 1;
            }
            else
            {
                info.NextBoxCode = arccate + "-" + arcyear + "-H-00001";
                info.NextBinCode = arccate + "-" + arcyear + "-X-00001"; 
                info.NextSortNum = 1;
            }
           
            return info;
        }

        private NextCodeSortInfo GetNextBinCode(string arccate, int arcyear)
        {
            var list = barLibService.GetLatestBoxBinCodes(arccate, arcyear, "BIN", "BarLib");

            List<BarLibEntity> lst = list.Result.ToList();
            NextCodeSortInfo info = new NextCodeSortInfo();

            if (lst.Count == 1)
            {
                BarLibEntity entity = lst[0];
                //箱码 + 1
                int pos = entity.Bincode.LastIndexOf('-');
                string prefix = entity.Bincode.Substring(0, pos + 1);
                string postfix = entity.Bincode.Substring(pos + 1);
                int num = int.Parse(postfix) + 1;
                info.NextBinCode = prefix + num.ToString().PadLeft(5, '0');
                info.NextBoxCode = "";
                info.NextSortNum = 0;
            }
            else
            {
                info.NextBoxCode = "";
                info.NextBinCode = arccate + "-" + arcyear + "-X-00001"; 
                info.NextSortNum = 1;
            }

            return info;
        }

        private string GetFullArchiveId(BarLibPrintParam param, int step)
        {
            int num = int.Parse(param.ArchiveIdStart) + step;

            return param.ArchiveType + "·" + param.ArchiveYear + "·" + num.ToString().PadLeft(5, '0');
        }
        #endregion


        /// <summary>
        /// 绑定周转箱码: 针对先前的盒码，写入它们对应的周转箱码，并产生一条周转箱码记录
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<TData<string>> BindTempBinCode(BarLibPrintParam param)
        {
            
            MatchCollection allMatchResults = null;

            //开始字符串 
            string s1 = " btn-info\">";
            //结束字符串 
            string s2 = "</button>";
            Regex rg = new Regex("(?<=(" + s1 + "))[.\\s\\S]*?(?=(" + s2 + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            //string str = rg.Match(s).Value;
            allMatchResults = rg.Matches(param.Description);
            string boxcodes = "";
            foreach (Match m in allMatchResults)
            {
                boxcodes += m.Value + ";";
            }

            TData<string> obj = new TData<string>();

            BarLibEntity entity = new BarLibEntity(); 

            entity.Boxcode = boxcodes;
            entity.Tempbincode = param.TempBinCode;
            entity.Arctype = param.ArchiveType;
            entity.Arcyear = param.ArchiveYear;
            entity.Category = "BIN";
            entity.Bincode = "-";
            await barLibService.BindTempBinCode(entity);

            // 将新的箱码，返回到前端页面显示出来
            obj.Result = entity.Tempbincode;
            obj.Description = entity.Id.ToString();

            obj.Tag = 1;

            return obj;
        }

    }
}
